<template>
  <div class="maintorPage" id="maintorPage">
    <header class="header">
      <div class="back" @click="back"><img src="~@/assets/monitor/back.png" alt="" />&ensp;返回</div>
      <!-- <div class="time"><img src="~@/assets/monitor/clock.png" alt=""/>&ensp;{{ time }}</div> -->
      <div class="time" style="position: relative; left: -26px">
        <p>工作站：{{ workstation.workName }}</p>
        <p>操作员：{{ nickname() }}</p>
        <span style="">当前车场监控时间</span>&ensp;{{ time }}
        <a-button type="primary" style="position: absolute; bottom: 36%; right: 0" @click="shift">换班</a-button>
      </div>
    </header>
    <section class="main">
      <div class="mainLeft" v-if="CameraType != 0">
        <div
          class="monitorScreen"
          :class="['length' + parkArms.length, { checked: index === checkedScreenIndex, error: parkArm.noScreen }]"
          v-for="(parkArm, index) in parkArms"
          :key="parkArm.id"
          @dblclick="fullScreenIndex = parkArm.id"
          @click="checkedScreenIndex = index"
        >
          <div class="corner topleft"></div>
          <div class="corner topright"></div>
          <div class="corner bottomleft"></div>
          <div class="corner bottomright"></div>
          <div class="monitorScreenHeader">
            <div class="monitorScreenHeaderLeft">
              <img class="car" src="~@/assets/monitor/car.png" alt="" />{{ parkArm.parkName }}>{{ parkArm.armName }}
              <a-select
                class="topLeftSelect"
                :options="armSelectOptions"
                :default-value="parkArm.id"
                @change="(value) => armSelectorChange(value, index)"
              ></a-select>
            </div>
            <div class="payTips" v-show="parkArm.show">
              <div class="item">
                <img src="../../assets/monitor/tips.png" alt="" />
                <div class="txt0">车牌号码：</div>
                <div class="txt1">{{ parkArm.plantNum }}</div>
              </div>
              <div class="item">
                <img class="op0" src="../../assets/monitor/tips.png" alt="" />
                <div class="txt0">支付金额：</div>
                <div class="txt2">{{ parkArm.payCont }}元</div>
              </div>
              <div class="item">
                <img class="op0" src="../../assets/monitor/tips.png" alt="" />
                <p class="txt0">支付类型：</p>
                <p class="txt3">{{ parkArm.payType }}</p>
              </div>
            </div>
          </div>

          <!-- <img src="" alt="" :id="'img' + parkArm.id" class="screenImg" v-show="!parkArm.noScreen" /> -->
          <div class="emergency" v-show="!parkArm.noScreen" @click="emergencyOpen(parkArm.serialNo)">应急开闸</div>
          <div class="emergency2" v-show="!parkArm.noScreen" @click="triggerExt(parkArm.serialNo)">重新识别</div>
          <div class="entryConfirm" v-if="parkArm.waitingEntry">
            <div class="content">
              {{ parkArm.waitingEntry.vehicleType }}
              &ensp;<span class="plateNo"> {{ parkArm.waitingEntry.plateNo }} </span>&ensp;申请进入车场。
              <br />

            </div>
            <div class="btns">
              <div class="reject" @click="rejectEntry(parkArm)">拒绝</div>
              <div class="accept" @click="acceptEntry(parkArm)">允许</div>
            </div>
          </div>
          <!-- id="vlc" -->
          <object
            style="width: 100%; height: 100%; position: relative; z-index: 1"
            type="application/x-vlc-plugin"
            events="True"
            pluginspage="http://www.videolan.org"
            codebase="http://downloads.videolan.org/pub/videolan/vlc/latest/win32/axvlc.cab"
          >
            <param name="mrl" :value="parkArm.rtspUrl" />
            <param name="volume" value="50" />
            <param name="autoplay" value="true" />
            <param name="loop" value="false" />
            <param name="fullscreen" value="false" />
            <param name="toolbar" value="false" />
            <param name="bgcolor" value="#fff" />
          </object>
        </div>
      </div>
      <div class="mainLeft" v-else>
        <div
          class="monitorScreen"
          :class="['length' + parkArms.length, { checked: index === checkedScreenIndex, error: parkArm.noScreen }]"
          v-for="(parkArm, index) in parkArms"
          :key="parkArm.id"
          @dblclick="fullScreenIndex = index"
          @click="checkedScreenIndex = index"
        >
          <div class="corner topleft"></div>
          <div class="corner topright"></div>
          <div class="corner bottomleft"></div>
          <div class="corner bottomright"></div>
          <div class="monitorScreenHeader">
            <div class="monitorScreenHeaderLeft">
              <img class="car" src="~@/assets/monitor/car.png" alt="" />{{ parkArm.parkName }}>{{ parkArm.armName }}
              <a-select
                class="topLeftSelect"
                :options="armSelectOptions"
                :default-value="parkArm.id"
                @change="(value) => armSelectorChange(value, index)"
              ></a-select>
            </div>
            <div class="payTips" v-show="parkArm.show">
              <div class="item">
                <img src="../../assets/monitor/tips.png" alt="" />
                <div class="txt0">车牌号码：</div>
                <div class="txt1">{{ parkArm.plantNum }}</div>
              </div>
              <div class="item">
                <img class="op0" src="../../assets/monitor/tips.png" alt="" />
                <div class="txt0">支付金额：</div>
                <div class="txt2">{{ parkArm.payCont }}元</div>
              </div>
              <div class="item">
                <img class="op0" src="../../assets/monitor/tips.png" alt="" />
                <p class="txt0">支付类型：</p>
                <p class="txt3">{{ parkArm.payType }}</p>
              </div>
            </div>
            <div class="monitorScreenHeaderRight">
              <div class="circle"></div>
              摄像头{{ parkArm.noScreen ? '连接异常' : '正常运行' }}
              <img class="fullscreen" src="~@/assets/monitor/fullscreen.png" alt="" @click="fullScreenIndex = index" />
            </div>
          </div>
          <img src="" alt="" :id="'img' + parkArm.id" class="screenImg" v-show="!parkArm.noScreen" />
          <div class="emergency" v-show="!parkArm.noScreen" @click="emergencyOpen(parkArm.serialNo)">应急开闸</div>
          <div class="emergency2" v-show="!parkArm.noScreen" @click="triggerExt(parkArm.serialNo)">重新识别</div>
          <div class="offline" v-show="parkArm.noScreen">
            <img src="~@/assets/monitor/offline.png" alt="" />
            <div>设备连接异常，无摄像头信号</div>
          </div>
          <div class="entryConfirm" v-if="parkArm.waitingEntry">
            <div class="content">
              {{ parkArm.waitingEntry.vehicleType }}&ensp;<span class="plateNo">{{ parkArm.waitingEntry.plateNo }}</span
              >&ensp;申请进入车场。
              <br />
            </div>
            <div class="btns">
              <div class="reject" @click="rejectEntry(parkArm)">拒绝</div>
              <div class="accept" @click="acceptEntry(parkArm)">允许</div>
            </div>
          </div>
          <a-modal
            :visible="index === fullScreenIndex"
            :footer="null"
            width="80%"
            :centered="true"
            :closable="false"
            :maskStyle="{ 'background-color': 'rgba(31, 31, 31, 0.9)' }"
            dialog-class="monitorScreenDialog"
          >
            <div class="monitorScreen dialog">
              <div class="monitorScreenHeader">
                <div class="monitorScreenHeaderLeft">
                  <img class="car" src="~@/assets/monitor/car.png" alt="" />{{ parkArm.parkName }}>{{ parkArm.armName }}
                </div>
                <div class="monitorScreenHeaderRight">
                  <div class="circle"></div>
                  摄像头{{ parkArm.noScreen ? '连接异常' : '正常运行' }}
                  <img class="restore" src="~@/assets/monitor/restore.png" alt="" @click="fullScreenIndex = -1" />
                </div>
              </div>
              <img src="" alt="" :id="'bigImg' + parkArm.id" class="screenImg" />
              <div class="emergency">应急开闸</div>
            </div>
          </a-modal>
        </div>
      </div>
      <div class="mainRight">
        <div class="corner topleft"></div>
        <div class="corner topright"></div>
        <div class="corner bottomleft"></div>
        <div class="corner bottomright"></div>
        <div class="mainRightHeader">{{ parkInfo.parkName }}</div>
        <ul class="mainRightBody">
          <li @click="totalParkSpaceEditModalShow = true">
            <div class="title"><img src="~@/assets/monitor/icon1.png" />停车场总车位</div>
            <div>
              <span class="number">{{ parkInfo.totalParkSpace }}</span
              >个
            </div>
          </li>
          <li>
            <div class="title"><img src="~@/assets/monitor/icon5.png" />剩余车位</div>
            <div>
              <span class="number">{{ parkInfo.remainingPark > 0 ? parkInfo.remainingPark : 0 }}</span
              >个
            </div>
          </li>
          <li>
            <div class="title"><img src="~@/assets/monitor/icon4.png" />场内临时车</div>
            <div>
              <span class="number">{{ parkInfo.parkSpace }}</span
              >个
            </div>
          </li>
          <li>
            <div class="title"><img src="~@/assets/monitor/icon2.png" />当日订单总数量</div>
            <div>
              <span class="number">{{ parkInfo.countOrder }}</span
              >个
            </div>
          </li>
          <li>
            <div class="title"><img src="~@/assets/monitor/icon3.png" />临时车现金收费</div>
            <div>
              <span class="number">{{ parkInfo.todayOrderSum }}</span
              >元
            </div>
          </li>
        </ul>
      </div>
    </section>
    <footer class="footer">
      <div class="corner topleft"></div>
      <div class="corner topright"></div>
      <div class="corner bottomleft"></div>
      <div class="corner bottomright"></div>
      <div class="footerLeft">
        <img v-show="!currentImgSrc" src="~@/assets/loginimg.png" alt="" />
        <img v-show="currentImgSrc" :src="currentImgSrc" alt="" @error="imgError" />
      </div>
      <div class="footerRight">
        <a-tabs default-active-key="1" @change="tabsChange">
          <a-tab-pane key="1" tab="入场信息">
            <a-table
              :pagination="false"
              :columns="enterColumns"
              :data-source="parkCarEnterLogs"
              :scroll="{ y: 188 }"
              :customRow="rowClick"
              rowKey="id"
            >
            </a-table>
          </a-tab-pane>
          <a-tab-pane key="2" tab="出场信息">
            <a-table
              :pagination="false"
              :columns="outColumns"
              :data-source="parkCarOutLogs"
              :scroll="{ y: 188 }"
              :customRow="rowClick"
              rowKey="id"
            >
            </a-table>
          </a-tab-pane>
          <a-tab-pane key="3" tab="订单信息">
            <a-table
              :pagination="false"
              :columns="orderColumns"
              :data-source="parkOrderInfos"
              :scroll="{ y: 188 }"
              :customRow="rowClick"
              rowKey="id"
            >
            </a-table>
          </a-tab-pane>
          <a-button v-has="'admin:parkCode'" type="link" slot="tabBarExtraContent" @click="more"> 更多</a-button>
        </a-tabs>
      </div>
    </footer>
    <div class="carModalWrap" v-show="orderInfos.length">
      <div class="carModal" v-for="(orderInfo, index) in orderInfos" :key="orderInfo.id">
        <div class="carModalHeader">
          {{ orderInfo.armName }}
          <a-icon type="close" @click="delOrder(index)" />
        </div>
        <div class="carModalMain">
          <div class="carModalLeft">
            <img :src="orderInfo.outImgPath" alt="" />
          </div>

          <div class="carModalRight">
            <div class="carModalRightHeader">
              <span>车牌号码：</span>
              <span class="carPlateNumber">{{ orderInfo.oncePlantNum }}</span>
            </div>
            <ul class="carModalRightContent">
              <div v-if="orderInfo.carEnterId">
                <li>
                  <div class="label">车辆类型：</div>
                  <div>
                    <a-select
                      size="large"
                      style="width: 150px"
                      :default-value="orderInfo.carTypeId"
                      @change="carTypeChange"
                    >
                      <a-select-option v-for="carType in carTypes" :key="orderInfo.id + carType.id" :value="carType.id">
                        {{ carType.carTypeName }}
                      </a-select-option>
                    </a-select>
                  </div>
                </li>
                <li>
                  <div class="label">入场时间：</div>
                  <div>{{ orderInfo.enterTime }}</div>
                </li>
                <li>
                  <div class="label">停车时长：</div>
                  <div>
                    {{ orderInfo.days ? orderInfo.days + '天' : '' }}
                    {{ orderInfo.hours ? orderInfo.hours + '小时' : '' }}
                    {{ orderInfo.minutes ? orderInfo.minutes + '分钟' : '' }}
                  </div>
                </li>
                <li>
                  <div class="label">应付金额：</div>
                  <div class="needPayMoney">{{ orderInfo.chargeUnpaid / 100 }}元</div>
                </li>
              </div>
              <div class="carModelLeftHeader" v-else>
                <div class="flexCenter" style="color: #fff; justify-content: center; margin-bottom: 10px">
                  <a-radio-group v-model="orderInfo.match" @change="onChange($event, index, orderInfo)">
                    <a-radio :value="true">匹配</a-radio>
                    <a-radio :value="false">补录</a-radio>
                  </a-radio-group>
                </div>
                <div class="flexCenter" v-show="orderInfo.match">
                  <div class="label" style="width: 80px">车辆匹配：</div>
                  <a-input
                    placeholder="请输入车牌号"
                    v-model="orderInfo.plateNo4Query"
                    :maxLength="4"
                    style="width: 257px"
                    class="iptStyle"
                    :disabled="!orderInfo.match"
                  ></a-input>
                </div>
                <div class="flexCenter" style="justify-content: center" v-show="orderInfo.match">
                  <a-button class="rightBtn footBtn" style="width: 100px" @click="getEnterLogsLikePlateNo(orderInfo)">确定</a-button
                  >
                </div>
                <a-table
                  class="atable"
                  :pagination="false"
                  :columns="CarMatchingColumns"
                  :data-source="orderInfo.carMatchingDataSource"
                  @change="handleTableChange"
                  v-show="orderInfo.matchLists"
                >
                  <span slot="action" slot-scope="text, record" style="display: flex; flex-direction: column">
                    <a @click="imgView(record.ossImgPath)">查看图片</a>
                    &ensp;
                    <a-popconfirm
                      title="确定匹配当前入场纪录吗?"
                      ok-text="是"
                      cancel-text="否"
                      @confirm="matchingEnterLogForCurrentOutCar(record, orderInfo)"
                    >
                      <a>重新计费</a>
                    </a-popconfirm>
                  </span>
                </a-table>
                <div v-show="!orderInfo.match">
                  <div class="flexCenter">
                    <div class="label">入场时间：</div>
                    <a-date-picker
                      class="datapick"
                      style="width: 257px"
                      :showTime="true"
                      :id="'datePicker' + orderInfo.serialNo"
                      :showToday="false"
                      :disabled-date="disabledDate"
                      placeholder="请补录入场时间"
                    />
                  </div>
                  <div class="flexCenter">
                    <div class="label">选择区域：</div>
                    <a-select
                      placeholder="请选择区域"
                      class="iptStyle"
                      size="large"
                      style="width: 257px"
                      @change="areaSelectorChange"
                    >
                      <a-select-option v-for="area in areaSelectOptions" :key="area.id" :value="area.id">
                        {{ area.areaName }}
                      </a-select-option>
                    </a-select>
                  </div>
                  <div class="flexCenter" style="justify-content: center">
                    <a-button
                      class="rightBtn footBtn"
                      style="width: 100px"
                      type="primary"
                      @click="makeupEnterLogConfirm(orderInfo)">确认补录</a-button
                      >
                  </div>
                </div>
              </div>
              <div v-show="!orderInfo.carEnterId">
                <li class="noEnterRecord">
                  <img src="~@/assets/monitor/warning.png" alt="" />
                  <div>未找到入场信息</div>
                </li>
              </div>
              <a-col v-has="'parkcode:paycost'">
                <li class="btn paidOpen" v-show="orderInfo.chargeUnpaid > 0" @click="open(orderInfo, index, false)">
                  缴费放行
                </li>
              </a-col>
              <a-col v-has="'parkcode:free'">
                <li class="btn freeOpen" @click="open(orderInfo, index, true)">免费放行</li>
              </a-col>
            </ul>
          </div>
        </div>
      </div>
    </div>
    <monitorShiftModal ref="shiftModal" @ok="shiftModalOk"></monitorShiftModal>
    <a-modal
      class="totalParkSpaceEditModal"
      v-model="totalParkSpaceEditModalShow"
      @ok="totalParkSpaceSave"
      title="停车场总车位修改"
    >
      总车位:<a-input-number
        :defaultValue="parkInfo.totalParkSpace"
        :min="0"
        @change="totalParkSpaceInputChange"
      ></a-input-number>
    </a-modal>
  </div>
</template>

<script>
/**
 * 视频监控的websocket连接，以及相应的心跳检测重连机制
 */

function ScreenWs(parkArm, index, vueContext) {
  this.parkArm = parkArm //车道信息
  this.parkArmIndex = index //车道下标
  this.vueContext = vueContext //vue中的this
}

ScreenWs.prototype.init = function () {
  this.create()
  this.vueContext.WebSockets.push(this)
}
ScreenWs.prototype.create = function () {
  try {
    console.log('视频WS create', this.parkArm.videoUrl)
    this.ws = new WebSocket(this.parkArm.videoUrl)
    this.initEventHandle()
  } catch (error) {
    // console.log('视频WS create代码执行失败')
    this.reconnect()
  }
}
ScreenWs.prototype.timerClean = function () {
  this.timer && clearTimeout(this.timer)
  this.reconnectTimer && clearTimeout(this.reconnectTimer)
}
ScreenWs.prototype.initEventHandle = function () {
  // console.log('视频WS事件绑定', this.parkArmIndex)
  this.ws.onopen = () => {
    // console.log('视频ws open', this.parkArmIndex)
    this.vueContext.parkArmStateChange(this.parkArm, this.parkArmIndex, false)
  }
  this.ws.onerror = () => {
    // console.log('视频wserror', this.parkArmIndex)
  }
  this.ws.onclose = (e) => {
    //ws因各种原因断开后重新创建ws连接
    console.log(e)
    if (this.forceClose) {
      // console.log('强制关闭视频ws', this.parkArmIndex)
      this.timerClean()
    } else {
      console.log('视频ws close', this.parkArmIndex)
      this.vueContext.parkArmStateChange(this.parkArm, this.parkArmIndex, true)
      this.reconnect()
    }
  }
  this.ws.onmessage = (event) => {
    clearTimeout(this.timer)
    if (this.parkArm.noScreen) {
      // console.log(this.parkArm.noScreen)
    }
    if (this.parkArm.noScreen === true) {
      this.vueContext.parkArmStateChange(this.parkArm, this.parkArmIndex, false)
    }
    this.timer = setTimeout(() => {
      //接收消息后10s内没有再次接收到消息时执行：当前车道没有画面，提示是否网络掉线等
      // console.log('已经十秒钟没有哦接收到画面了', this.parkArmIndex)
      this.ws.close()
    }, 10000)
    let imgDom = document.getElementById('img' + this.parkArm.id)
    if (imgDom === null) {
      return
    }
    let reader = new FileReader()
    let that = this
    reader.onload = function (readerEvent) {
      if (readerEvent.target.readyState === FileReader.DONE) {
        imgDom.src = this.result
        if (that.vueContext.fullScreenIndex === that.parkArmIndex) {
          document.getElementById('bigImg' + that.vueContext.parkArms[that.vueContext.fullScreenIndex].id).src =
            this.result
        }
      }
    }
    reader.readAsDataURL(event.data)
  }
}
ScreenWs.prototype.reconnect = function () {
  // console.log('视频WS reconert')
  if (this.lockReconnect) return
  this.lockReconnect = true
  //没连接上会一直重连，设置延迟避免请求过多
  this.timerClean()
  this.reconnectTimer = setTimeout(() => {
    // console.log('重连定时器函数执行', this.parkArmIndex)
    this.create()
    this.lockReconnect = false
  }, 2000)
}
ScreenWs.prototype.close = function () {
  this.forceClose = true
  this.timerClean()
  this.ws.close()
}
import Vue from 'vue'
import moment from 'moment'
import { ACCESS_TOKEN, USER_NAME, USER_INFO} from '@/store/mutation-types'
import { welcome } from '@/utils/util'
import { getAction, httpAction, postAction, putAction } from '@/api/manage'
import { mapGetters } from 'vuex'
import monitorShiftModal from './modules/monitorShiftModal'
export default {
  name: 'Monitor',
  components: {
    monitorShiftModal,
  },
  data() {
    return {
      workstation: {},
      isNoEnterRecord: true, //标记是否没有入场记录
      carModalVisible: true, //是否显示车辆出场时的模态框
      timer: null, //右上角日期时间更新定时器
      time: new Date().toLocaleString(), //右上角的日期时间
      mac: null, //本机mac地址
      checkedScreenIndex: 0, //点击选中的视频画面的索引
      fullScreenIndex: -1, //全品的视频画面索引
      carNatures: ['临时车', '月租车', '储值车', '军警车', '白名单'], //车辆类型，用于页面下方图表显示
      parkArms: [], //车道信息
      parkNoImagePath: null,
      totalParkSpaceInput: 0, //编辑车场总车位时输入的数字
      totalParkSpaceEditModalShow: false,
      parkInfo: {
        //页面右侧当前车场相关信息
        parkName: '',
        totalParkSpace: 0, //总车位
        remainingPark: 0, //剩余车位
        parkSpace: 0, //临时车
        countOrder: 0, //订单数
        todayOrderSum: 0.0, //总订单金额
      },
      payTypes: ['微信', '支付宝', '无感支付', '全免券', '储值卡', '线下缴费'],
      enterColumns: [
        //入场列表表头
        {
          title: '车牌号码',
          dataIndex: 'plateNo',
        },
        {
          title: '车辆类型', //0:临时车,1:月租车2:军警车
          dataIndex: 'carNature',
          key: 'carNature',
          // customRender: (text) => this.carNatures[text],
          customRender: (v,record) =>{
            if(v==="0" || v===0){
              if(record.carTypeNo ==="-1" || record.carTypeNo === -1){
                return "内部车";
              }
              return '临时车'
            } else if (v === '1' || v === 1) {
              return '月租车'
            } else if (v === '2' || v === 2) {
              return '储值车'
            } else if (v === '3' || v === 3) {
              return '军警车'
            } else if (v === '4' || v === 4) {
              return '白名单'
            }
          },
        },
        {
          title: '入场地点',
          dataIndex: 'armName',
          key: 'armName',
        },
        {
          title: '停车状态',
          dataIndex: 'isOut',
          key: 'isOut',
          customRender(text) {
            return text === '0' ? '场内' : '出场'
          },
        },
        {
          title: '入场时间',
          dataIndex: 'carEnterTime',
          key: 'carEnterTime',
        },
      ],
      outColumns: [
        //出场列表表头
        {
          title: '车牌号码',
          dataIndex: 'plateNo',
          key: 'plateNo',
        },
        {
          title: '车辆类型',
          dataIndex: 'carNature',
          key: 'carNature',
          // customRender: (text) => this.carNatures[text],
          customRender: (v,record) =>{
            if(v==="0" || v===0){
              if(record.carTypeNo ==="-1" || record.carTypeNo === -1){
                return "内部车";
              }
              return '临时车'
            } else if (v === '1' || v === 1) {
              return '月租车'
            } else if (v === '2' || v === 2) {
              return '储值车'
            } else if (v === '3' || v === 3) {
              return '军警车'
            } else if (v === '4' || v === 4) {
              return '白名单'
            }
          },
        },
        {
          title: '出口',
          dataIndex: 'armName',
          key: 'armName',
          customRender: (text) => text || '无',
        },
        {
          title: '出场时间',
          dataIndex: 'createTime',
          key: 'createTime',
        },
      ],
      orderColumns: [
        //订单列表表头,
        {
          title: '车牌号码',
          dataIndex: 'plateNo',
          key: 'plateNo',
        },
        {
          title: '订单费用(元)',
          dataIndex: 'chargePaid',
          key: 'chargePaid',
          customRender: (text) => (text / 100).toFixed(2),
        },
        {
          title: '缴费方式', //1微信，2支付宝,3无感支付,4全免券,5储值卡，6线下收费
          dataIndex: 'payType',
          key: 'payType',
          customRender: (text) => this.payTypes[text - 1],
        },
        {
          title: '缴费时间',
          dataIndex: 'createTime',
          key: 'createTime',
          ellipsis: true,
        },
      ],
      CarMatchingColumns: [
        //车牌匹配表头
        {
          title: '车牌号',
          align: 'center',
          dataIndex: 'plateNo',
        },
        {
          title: '入场时间',
          align: 'center',
          dataIndex: 'carEnterTime',
        },
        {
          title: '操作',
          dataIndex: 'action',
          align: 'center',
          scopedSlots: { customRender: 'action' },
        },
      ],
      // plateNo4Query: '', //出场异常时手动输入车牌号
      parkCarEnterLogs: [], //入场记录列表数据
      parkCarOutLogs: [], //出场记录列表数据
      parkOrderInfos: [], //订单列表数据
      WebSockets: [], //车道视频链接的websocket
      carTypes: [], //车辆类型下拉列表
      //当前ws推送的订单信息
      orderInfos: [],
      //当前标签页key值
      tabsActiveKey: 1,
      currentImgSrc: '', //列表左侧显示的图片路径
      keyUpTimer: null,
      serverWSHeartCheck: null,
      serverWS: null,
      serverWsForceClose: false,
      allParkArm: null, //当前车场的所有车道
      armSelectOptions: null, //车道切换的selector选择项
      areaSelectOptions: null, //区域的selector选择项
      areaId: null,
      currentPlant: null,
      oncePlantNumFlag: true,
      closeTipsFlag: true,
      url: {
        getHandOverData: '/operationLog/parkHandOverLog/getHandOverData',
        editTemporary: '/parking/configParkInfo/editTemporary',
        getUserId: '/sys/getUserId',
      },
      serverWSUrl: '', //与服务器连接的websocket url

      CameraType: -1, // websoket (==0) and rtsp(!=0)

      openloader:false,
    }
  },
  methods: {
    //切换相机后，将userId更改
    saveArmMac: function (newArmId, index) {
      let params = {
          newArmId: newArmId,
          oldArmId: this.parkArms[index].id,
        },
        arm,
        newArm,
        newOptions,
        { CameraType } = this
      postAction('/parking/parkArmInfo/saveArmMac', params).then((res) => {
        if (res.code === 200) {
          if (CameraType == 0) {
            console.log('更改成功')
            //查找将要显示的车道
            arm = this.allParkArm.find((item) => item.id === newArmId)
            newArm = { ...arm }
            //限制当前出口车道数量不能超过2个
            if (this.currentOutArmScreenNum >= 2 && arm.armType === '1') {
              this.$message.info('出口车道最多只能显示两个')
              return
            }
            //断开当前车道视频连接
            this.WebSockets[index].close()
            // 更改armSelectOptions数据,把新车道设为disabled=true,原车道设为false
            newOptions = [...this.armSelectOptions]
            newOptions.forEach((item) => {
              if (item.value === this.parkArms[index].id) {
                item.disabled = false
              } else if (item.value === newArm.id) {
                item.disabled = true
              }
            })
            this.armSelectOptions = newOptions
            // 更新数据,使页面ui响应
            this.parkArms.splice(index, 1, newArm)
            // 建立新的websock连接
            let ws = new ScreenWs(newArm, index, this)
            ws.create()
            //更新websocket数组
            this.WebSockets.splice(index, 1, ws)
            console.log(this.WebSockets)
            return
          }

          //操作成功
          console.log('更改成功')
          //查找将要显示的车道
          arm = this.allParkArm.find((item) => item.id === newArmId)
          newArm = { ...arm }
          //限制当前出口车道数量不能超过2个
          if (this.currentOutArmScreenNum >= 2 && arm.armType === '1') {
            this.$message.info('出口车道最多只能显示两个')
            return
          }
          newOptions = [...this.armSelectOptions]
          newOptions.forEach((item) => {
            if (item.value === this.parkArms[index].id) {
              item.disabled = false
            } else if (item.value === newArm.id) {
              item.disabled = true
            }
          })
          this.armSelectOptions = newOptions
          let mainLeft = document.getElementsByClassName('mainLeft')[0]
          this.parkArms[index] = arm
          mainLeft.insertBefore(mainLeft.children[index], mainLeft.childNodes[index])
        } else {
          this.$message.info('操作失败')
        }
      })
    },
    async getData() {
      let params = { userId: this.userInfo.id, workstationId: this.workstation.id }
      await getAction('/parking/parkArmInfo/getData', params).then((response) => {
        if (response.success) {
          let result = response.result
          this.parkInfo.totalParkSpace = result.totalParkSpace //总车位
          this.parkInfo.remainingPark = result.remainingPark //剩余车位
          this.parkInfo.parkSpace = result.parkSpace //临时车
          this.parkInfo.countOrder = result.countOrder //订单数
          this.parkInfo.todayOrderSum = result.todayOrderSum //总订单金额
          this.parkInfo.parkName = result.parkName
          this.parkCarEnterLogs = result.parkCarEnterLogs
          this.parkCarOutLogs = result.parkCarOutLogs
          this.parkOrderInfos = result.parkOrderInfos
          this.CameraType = result.CameraType
          if (result.parkArm.length > 4) {
            result.parkArm = result.parkArm.slice(0, 4)
          }
            // result.parkArm.forEach((parkArm) => {
            //   parkArm.noScreen = true
            // })
          this.parkArms = result.parkArm
          this.carTypes = result.carType
          this.allParkArm = result.allParkArm
          this.parkArm = result.parkArm
          this.armSelectOptions = this.allParkArm.map((item) => {
            return {
              value: item.id,
              label: item.armName,
              disabled: this.parkArm.findIndex((e) => e.id == item.id) != -1,
            }
          })
          console.log(this.userInfo.id, this.armSelectOptions)
          // return
          this.CameraType == 0 &&
            this.$nextTick(() => {
              this.WebSockets = []
              this.parkArms.forEach((parkArm, index) => {
                if (parkArm) {
                  let screenWs = new ScreenWs(parkArm, index, this)
                  screenWs.init()
                  // this.WebSockets.push(screenWs)
                }
              })
            })
        }
      })
    },
    ...mapGetters(['nickname']),
    totalParkSpaceInputChange(value) {
      this.totalParkSpaceInput = value
    },
    totalParkSpaceSave() {
      putAction(this.url.editTemporary, { temporaryParking: this.totalParkSpaceInput }).then((res) => {
        console.log(res)
        if (res.code === 200) {
          this.parkInfo.totalParkSpace = this.totalParkSpaceInput
          this.totalParkSpaceEditModalShow = false
          // this.$forceUpdate();
        }
        this.$message[res.code === 200 ? 'success' : 'error'](res.message)
      })
    },
    shiftModalOk(result) {
      let userInfo = result.userInfo
      let commit = this.$store.commit
      Vue.ls.set(ACCESS_TOKEN, result.token)
      Vue.ls.set(USER_NAME, userInfo.username)
      Vue.ls.set(USER_INFO, userInfo)
      commit('SET_TOKEN', result.token)
      commit('SET_INFO', userInfo)
      commit('SET_NAME', {
        username: userInfo.username,
        realname: userInfo.realname,
        welcome: welcome(),
      })
      commit('SET_ROUTERS', [])
      commit('SET_PERMISSIONLIST', [])
      this.getData()
      this.setServerWSUrl()
      this.serverWS.close()
    },
    requestFullScreen() {
      var docElm = document.documentElement
      if (docElm.requestFullscreen) {
        docElm.requestFullscreen()
      } else if (docElm.msRequestFullscreen) {
        docElm.msRequestFullscreen()
      } else if (docElm.mozRequestFullScreen) {
        docElm.mozRequestFullScreen()
      } else if (docElm.webkitRequestFullScreen) {
        docElm.webkitRequestFullScreen()
      }
    },
    // 换班
    shift(record) {
      this.$refs.shiftModal.title = '换班'
      this.$refs.shiftModal.edit(record)
    },
    onChange(e, index, orderinfo) {
      console.log(e.target.value, index, orderinfo)
      this.orderInfos[index].match = e.target.value
      if (!e.target.value) {
        this.orderInfos[index].matchLists = false
        this.makeupEnterLog(orderinfo)
      }
      this.orderInfos[index].plateNo4Query = e.target.value ? '' : '点击确定开始补录'
    },
    PayFormDate(item, index) {
      this.orderInfos[index].chargeUnpaid = item * 100
      this.$set(this.orderInfos, index, this.orderInfos[index])
    },
    armSelectorChange(armId, index) {
      //切换车道
      //armId,新车道id
      //this.parkArms[index].id,旧车道的id
      //先更换一下新旧车道的mac，更换成功的话，再走切换监控的逻辑
      this.saveArmMac(armId, index, this.userInfo.id)
    },

    // 获取区域列表id
    getAreaSelects() {
      getAction('/area/parkAreaInfo/getAreaInfos', {}).then((res) => {
        if (res.code === 200) {
          this.areaSelectOptions = res.result
          this.$notification.open({
            message: '提示：',
            description: '请选择补录日期、补录区域',
            onClick: () => {
              console.log('-')
            },
          })
        } else {
          this.$message.info('操作失败')
        }
      })
    },
    // 区域id列表选择
    areaSelectorChange(val) {
      //console.log('选择的区域', val)
      this.areaId = val
    },

    acceptEntry(parkArm) {
      //允许车辆进场
      postAction('/sdkidentifyresultpushlog/sdkIdentifyResultPushLog/openedSaveParkCarEnterLog', {
        serialNo: parkArm.waitingEntry.serialNo,
        plateNo: parkArm.waitingEntry.plateNo,
        carNature: parkArm.waitingEntry.vehicleType,
        areaId: this.areaId,
      }).then((res) => {
        if (res.code === 200) {
          //操作成功
          this.$message.info('操作成功')
          this.armInfoDelData(parkArm)
        } else {
          this.$message.info(res.message || '服务异常,操作失败')
        }
      })
    },
    rejectEntry(parkArm) {
      //拒绝车辆进场
      postAction('/sdkidentifyresultpushlog/sdkIdentifyResultPushLog/refuseCarEnter', {
        serialNo: parkArm.waitingEntry.serialNo,
        plateNo: parkArm.waitingEntry.plateNo,
      }).then((res) => {
        this.$message.info(res.message)
        if (res.code === 200) {
          this.armInfoDelData(parkArm)
        }
      })
    },
    disabledDate(current) {
      //禁止选择此刻之后的时间
      return moment().isBefore(current)
    },
    makeupEnterLogConfirm(orderInfo) {
      //确认补录
      let date = document.getElementById('datePicker' + orderInfo.serialNo).getElementsByTagName('input')[0].value
      if (!date) {
        this.$message.info('先选择入场时间后,才能补录。')
        return
      }
      if (this.areaId === null || this.areaId === '' || this.areaId === undefined) {
        this.$message.error('请选择区域信息')
        return
      }
      let params = {
        plateNo: orderInfo.plateNo,
        parkCode: orderInfo.parkCode,
        enterDate: date,
        areaId: this.areaId,
        serialNo: orderInfo.serialNo,
        ossImgPath: orderInfo.ossImgPath,
      }
      console.log(params)
      postAction(
        '/sdkidentifyresultpushlog/sdkIdentifyResultPushLog/againChargeSaveEnterForCurrentOutCar',
        params
      ).then((res) => {
        let newOrderInfo = Object.assign({ matching: true }, orderInfo, res.result, { makingUp: false }) //使用matching保持ui显示
        this.durationParse(newOrderInfo)
        this.orderInfoUpdate(newOrderInfo)
        if (res.result.orderStatus == '2') {
          this.prePay(newOrderInfo)
        }
      })
    },
    // 储值车逻辑单独处理
    prePay(newOrderInfo) {
      let findIndex = this.orderInfos.findIndex((item) => {
        return item.serialNo === newOrderInfo.serialNo
      })
      if (findIndex !== -1) {
        this.delOrder(findIndex)
      }
    },
    makeupEnterLog(orderInfo) {
      //补录入场记录
      orderInfo.makingUp = true
      this.orderInfoUpdate(orderInfo)
      // 获取区域id
      this.getAreaSelects()
    },
    orderInfoUpdate(orderInfo) {
      //更新orderInfo
      let findIndex = this.orderInfos.findIndex((item) => {
        return item.serialNo === orderInfo.serialNo
      })
      if (findIndex > -1) {
        this.$set(this.orderInfos, findIndex, orderInfo)
      } else {
        this.orderInfos.push(orderInfo)
      }
    },
    // 支付弹窗 serialNo
    payTipsShow(dataobj) {
      let findIndex = this.parkArms.findIndex((item) => {
        return item.serialNo === dataobj.serialNo
      })
      console.log('匹配的车道findIndex', findIndex)
      if (findIndex > -1) {
        // 支付类型：1微信，2支付宝,3无感支付，4,全免劵，5储值车，6线下收费
        let patTypeTxt = ''
        switch (dataobj.payType) {
          case '1':
            patTypeTxt = '微信'
            break
          case '2':
            patTypeTxt = '支付宝'
            break
          case '3':
            patTypeTxt = '无感支付'
            break
          case '4':
            patTypeTxt = '全免劵'
            break
          case '5':
            patTypeTxt = '储值车'
            break
          case '6':
            patTypeTxt = '线下收费'
            break
          default:
            patTypeTxt = '未知'
            break
        }
        let newArmInfo = Object.assign({}, this.parkArms[findIndex], {
          plantNum: dataobj.plateNo,
          payType: patTypeTxt,
          payCont: (dataobj.chargeTotalFee * 100) / 10000,
          show: true,
        })
        console.log('支付弹窗newArmInfo', newArmInfo)
        this.$set(this.parkArms, findIndex, newArmInfo)
        setTimeout(() => {
          this.parkArms[findIndex].show = false
        }, 5000)
      }
    },
    durationParse(parkOrderInfo) {
      //将分钟单位的停车时长转换为xx天xx小时xx分
      parkOrderInfo.days = 0
      parkOrderInfo.hours = 0
      parkOrderInfo.minutes = 0
      var day = parseInt(parkOrderInfo.chargeDuration / 60 / 24)
      var hour = parseInt((parkOrderInfo.chargeDuration / 60) % 24)
      var min = parseInt(parkOrderInfo.chargeDuration % 60)
      // parkOrderInfo.chargeDuration = ''
      if (day > 0) {
        parkOrderInfo.days = day
      }
      if (hour > 0) {
        parkOrderInfo.hours = hour
      }
      if (min > 0) {
        parkOrderInfo.minutes = parseFloat(min)
      }
    },
    imgView(src) {
      // 遮罩层
      let divEle = document.createElement('div')
      divEle.className = 'imgViewer'
      divEle.setAttribute(
        'style',
        `position:fixed;left:0;right:0;top:0;bottom:0;background-color:rgba(0,0,0,.8);display:flex;justify-content:center;align-items:center;z-index:9999;`
      )
      // 图片容器
      let imgWrapEle = document.createElement('div')
      imgWrapEle.setAttribute(
        'style',
        `position:relative;border:1px solid #ddd;border-radius:4px;max-width:80%;padding:15px;`
      )
      divEle.appendChild(imgWrapEle)
      // 关闭按钮
      let closeEle = document.createElement('span')
      closeEle.innerHTML = 'X' //这个关闭按钮的src根据项目中的图片路径去写
      closeEle.setAttribute(
        'style',
        `position:absolute;top:-25px;right:-25px;border:1px solid #fff;color:#fff;border-radius:50%;width:1em;height:1em;display: flex;flex-direction: row;flex-wrap: wrap;align-content: center;justify-content: center;font-size: 18px;cursor: pointer;`
      )
      closeEle.addEventListener('click', function (e) {
        if (this === e.target) {
          divEle.remove()
        }
      })
      imgWrapEle.appendChild(closeEle)
      // 图片
      let imgEle = document.createElement('img')
      imgEle.src = src
      imgEle.setAttribute('style', `max-width:100%;max-height:100%;`)
      imgWrapEle.appendChild(imgEle)
      // 放入到body中
      document.body.appendChild(divEle)
    },
    outConfirmHandleOk() {
      this.outConfirmVisible = false
    },
    handleTableChange(pagination, filters, sorter) {
      //分页、排序、筛选变化时触发
      //TODO 筛选
      if (Object.keys(sorter).length > 0) {
        this.isorter.column = sorter.field
        this.isorter.order = 'ascend' == sorter.order ? 'asc' : 'desc'
      }
      this.ipagination = pagination
      this.loadData()
    },
    initKeyUpEnter() {
      var _this = this
      document.onkeydown = function (e) {
        //防止在input输入框输入内容时触发该事件
        if (e.target !== document.body) {
          return
        }
        if (_this.orderInfos.length !== 1) {
          return
        }
        let key = window.event.keyCode
        if (key === 13 || key === 32) {
          if (_this.keyUpTimer) {
            clearTimeout(_this.keyUpTimer)
          }
          _this.keyUpTimer = window.setTimeout(() => {
            let orderInfo = _this.orderInfos[0]
            _this.open(orderInfo, 0, false)
            clearTimeout(_this.keyUpTimer)
          }, 500)
        }
      }
    },
    imgError() {
      console.log('error')
      this.currentImgSrc = ''
    },
    rowClick(record) {
      let that = this
      return {
        on: {
          click() {
            that.currentImgSrc = record.imgPath
            console.log(that.currentImgSrc)
          },
        },
      }
    },
    setServerWSUrl() {
      //生产环境地址
      this.serverWSUrl = "ws://"+location.hostname+"/park-single/websocket/" + this.userInfo.id;

    },
    serverWSCreate() {
      //与后台服务的ws连接
      this.setServerWSUrl()
      let lockReconnect = false
      let reconnectTimer // websocket重连定时器
      let that = this,
        timeoutTimer = null, // websocket心跳定时器
        timeout = 10000, // websocket心跳定时器间隔时间 10秒
        reconnectTimeuot = 2000 //  websocket重连定时器间隔时间 2秒

      function create() {
        try {
          console.log('创建与服务端的连接')
          that.serverWS = new WebSocket(that.serverWSUrl)
          initEventHandle()
        } catch (error) {
          console.log('创建与服务端的连接代码异常', error)
          reconnect()
        }
      }

      let initEventHandle = () => {
        console.log('与服务端的ws事件绑定')
        that.serverWS.onopen = () => {
          console.log('与服务端的连接open')
          timeoutTimer && clearInterval(timeoutTimer) // 清除心跳定时器
          timeoutTimer = setInterval(function () {
            console.log('与服务端的连接心跳timeoutTimer处理函数执行')
            that.serverWS.send('ping')
          }, timeout)
        }
        that.serverWS.onmessage = () => {
          console.log('与服务端的连接message')
          if (event.data === '连接成功') {
            return
          }
          let data = JSON.parse(event.data)
          console.log(data)
          if (data.parkOrderInfo) {
            that.oncePlantNumFlag = true
            //有车辆出场
            if (that.oncePlantNumFlag) {
              data.parkOrderInfo.oncePlantNum = data.parkOrderInfo.plateNo
            }

            that.durationParse(data.parkOrderInfo)
            that.orderInfoUpdate(data.parkOrderInfo)
            // 没有入场纪录
            if (!data.parkOrderInfo.carEnterId) {
              data.parkOrderInfo.plateNo4Query = ''
              data.parkOrderInfo.matchLists = false
              data.parkOrderInfo.match = true
              this.$nextTick(() => {
                console.log(data.parkOrderInfo.plateNo)
                this.AutoMatchingEnterLog(data.parkOrderInfo)
              })
            }
          } else if (data.parkOrderInfos) {
            //车场统计信息
            this.parkCarEnterLogs = data.parkCarEnterLogs
            this.parkCarOutLogs = data.parkCarOutLogs
            this.parkOrderInfos = data.parkOrderInfos
            Object.assign(this.parkInfo, data)
          } else if (data.successOrder) {
            let findIndex = this.orderInfos.findIndex((item) => {
              //避免同车道车辆重复显示
              return item.serialNo === data.successOrder.serialNo
            })
            if (findIndex !== -1) {
              that.delOrder(findIndex)
            }
            that.payTipsShow(data.successOrder)
          } else if (data.armType === '0') {
            //车辆申请进入消息
            that.armInfoAddData(data)
          }
        }
        that.serverWS.onclose = () => {
          console.log('与服务端的连接close', `是否退出监控:${that.serverWsForceClose}`)
          if (that.serverWsForceClose) {
            console.log('退出服务连接')
            timeoutTimer && clearInterval(timeoutTimer) // 清除心跳定时器
            reconnectTimer && clearTimeout(reconnectTimer) // 清除重连定时器
            return
          }
          reconnect()
        }
        that.serverWS.onerror = (error) => {
          // debugger;
          console.log('与服务端的连接error', error)
          reconnect()
        }
      }

      function reconnect() {
        timeoutTimer && clearInterval(timeoutTimer) // 清除心跳定时器
        console.log('与服务端的连接reconnect')
        console.log('lockReconnect:', lockReconnect)
        if (lockReconnect) return
        lockReconnect = true
        reconnectTimer && clearTimeout(reconnectTimer) // 清除重连定时器
        reconnectTimer = setTimeout(() => {
          console.log('lockReconnect:', lockReconnect)
          create()
          lockReconnect = false
        }, reconnectTimeuot)
      }

      create()
    },
    armInfoAddData(data) {
      //更新车道数据，显示车辆进入的消息
      let findIndex = this.parkArms.findIndex((item) => item.id === data.armId)
      if (findIndex > -1) {
        let newArmInfo = Object.assign({}, this.parkArms[findIndex], { waitingEntry: data })
        this.$set(this.parkArms, findIndex, newArmInfo)
      }
    },
    armInfoDelData(parkArm) {
      //更新车道数据，隐藏车辆进入的消息
      let findIndex = this.parkArms.findIndex((item) => item.id === parkArm.id)
      if (findIndex > -1) {
        let newArmInfo = Object.assign({}, this.parkArms[findIndex], { waitingEntry: null })
        this.$set(this.parkArms, findIndex, newArmInfo)
      }
    },
    getEnterLogsLikePlateNo(orderInfo) {
      let plateNo = orderInfo.plateNo4Query || ''
      getAction('/sdkidentifyresultpushlog/sdkIdentifyResultPushLog/findLikePlateNo?plateNo=' + plateNo).then((res) => {
        let newOrderInfo
        if (res.success) {
          newOrderInfo = Object.assign({}, orderInfo, { carMatchingDataSource: res.result })
        }
        if (res.result.length === 0) {
          this.getAreaSelects()
          newOrderInfo.match = false
          newOrderInfo.matchLists = false
          newOrderInfo.plateNo4Query = '点击确定开始补录'
          this.$notification.open({
            message: '提示：',
            description: '未匹配到车牌号，请点击确定按钮开始补录',
            onClick: () => {
              //console.log('-')
            },
          })
        } else {
          newOrderInfo.match = true
          newOrderInfo.matchLists = true
        }
        newOrderInfo.makingUp = false
        this.orderInfoUpdate(newOrderInfo)
      })
    },
    AutoMatchingEnterLog(orderInfo) {
      getAction(
        '/sdkidentifyresultpushlog/sdkIdentifyResultPushLog/AutoMatchingEnterLogForCurrentOutCar?plateNo=' +
          orderInfo.plateNo
      ).then((res) => {
        if (res.success) {
          let newOrderInfo = Object.assign({}, orderInfo, { carMatchingDataSource: res.result })
          this.orderInfoUpdate(newOrderInfo)
        }
      })
    },
    matchingEnterLogForCurrentOutCar(record, orderInfo) {
      httpAction(
        '/sdkidentifyresultpushlog/sdkIdentifyResultPushLog/againChargeForCurrentOutCar',
        {
          outPlateNo: orderInfo.oncePlantNum,
          parkCode: record.parkCode,
          plateNo: record.plateNo,
          serialNo: orderInfo.serialNo,
          ossImgPath: orderInfo.ossImgPath,
        },
        'post'
      ).then((res) => {
        this.oncePlantNumFlag = false
        let newOrderInfo = Object.assign({ matching: true }, orderInfo, res.result)
        newOrderInfo.matchLists = false
        this.durationParse(newOrderInfo)
        this.orderInfoUpdate(newOrderInfo)
      })
    },
    carTypeChange(value, option) {
      const that = this
      //车辆类型手动更改
      let findIndex = this.orderInfos.findIndex((item) => {
        return item.id === option.key.replace(value, '')
      })
      let newOrderInfo = Object.assign({}, this.orderInfos[findIndex])
      newOrderInfo.carTypeId = value
      this.$set(this.orderInfos, findIndex, newOrderInfo)
      postAction('/parking/parkCharge/parkChargeFee', newOrderInfo).then((res) => {
        if (res.success) {
          newOrderInfo.chargeTotalFee = res.result.chargeTotalFee
          newOrderInfo.chargeUnpaid = res.result.chargeUnpaid
          that.$set(that.orderInfos, findIndex, newOrderInfo)
        } else {
          newOrderInfo.chargeTotalFee = 0
          newOrderInfo.chargeUnpaid = 0
          that.$set(that.orderInfos, findIndex, newOrderInfo)
        }
        that.$message[res.success ? 'success' : 'error'](res.message)
      })
    },
    delOrder(index) {
      //关闭显示当前的订单消息窗口
      if (this.closeTipsFlag) {
        this.closeTipsFlag = false
        this.orderInfos.splice(index, 1)
        // 防止重复触发
        setTimeout(() => {
          this.closeTipsFlag = true
        }, 800)
      }
    },
    back() {
      //返回按钮事件
      this.exitFullScreen()
    },
    exitFullScreen() {
      //退出全屏
      if (!document.fullscreenElement) {
        if (this.$route.name === 'Monitor') {
          this.$router.back()
        }
        return
      }
      if (document.exitFullscreen) {
        document.exitFullscreen()
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen()
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen()
      } else if (document.webkitCancelFullScreen) {
        document.webkitCancelFullScreen()
      }
    },
    getHandOverData() {
      getAction(this.url.getHandOverData, { userId: this.userInfo.id }).then((res) => {
        this.workstation = res.result
        this.getData()
      })
    },
    timeInterval() {
      //启动日期刷新定时器
      this.timer = setInterval(() => {
        this.time = new Date().toLocaleString()
      }, 1000)
    },
    open(orderInfo, orderIndex, isFree) {
      if(this.openloader)return
      this.openloader = true
      //缴费放行、免费放行
      orderInfo = Object.assign({}, orderInfo)
      if (!isFree) {
        // 缴费放行
        orderInfo.orderStatus = 2
      }
      postAction('/sdk/ioUnfold', orderInfo).then((res) => {
        if (res.success) {
          this.delOrder(orderIndex)
        }
        //将message显示出来
        this.$message[res.success ? 'success' : 'error'](res.message)
        this.openloader = false
      })
    },
    emergencyOpen(serialNo) {
      //应急开闸
      getAction('sdk/unfold', { serialNo }).then((res) => {
        this.$message[res.success ? 'success' : 'error'](res.message)
      })
    },
    triggerExt(serialNo) {
      //应急开闸
      getAction('/sdkidentifyresultpushlog/sdkIdentifyResultPushLog/triggerExt', { serialNo }).then((res) => {
        this.$message[res.success ? 'success' : 'error'](res.message)
      })
    },
    tabsChange(key) {
      this.tabsActiveKey = key
    },
    more() {
      this.$router.push(
        [
          '/parking/parkCarEnterLog/parkCarEnterLogList',
          '/parking/parkCarOutLog/parkCarOutLogList',
          '/order/ParkOrderInfoList',
        ][this.tabsActiveKey - 1]
      )
    },
    wsDestroy() {
      console.log('destroy')
      this.WebSockets.forEach((item) => {
        item.close()
      })
      this.serverWsForceClose = true
      this.serverWS && this.serverWS.close()
    },
    parkArmStateChange(parkArm, parkArmIndex, noScreen) {
      parkArm.noScreen = noScreen
      this.parkArms.splice(parkArmIndex, 1, Object.assign({}, parkArm))
    },
  },
  mounted() {
    //监听退出全屏事件（根据resize事件判断），调用this.back函数
    var that = this
    document.onfullscreenchange = () => {
      if (!document.fullscreenElement) {
        if (that.$route.name === 'Monitor') {
          that.$router.back()
        }
      }
    }
    this.initKeyUpEnter()
  },
  created() {
    this.getHandOverData()
    this.timeInterval()
    this.serverWSCreate()
  },
  computed: {
    ...mapGetters(['userInfo']),

    currentOutArmScreenNum() {
      let num = 0
      this.parkArms.forEach((item) => {
        if (item.armType === '1') {
          num++
        }
      })
      return num
    },
  },
  beforeDestroy(){
    this.wsDestroy();
  }
}
</script>

<style scoped lang="less">
::v-deep .ant-select-selection-selected-value {
  color: #000;
}
::v-deep .ant-modal-wrap {
  z-index: 1009;
}
.maintorPage {
  color: #83c3ff;
  padding: 17px 40px;
  background-color: #171e30;
  min-height: 100%;

  .header {
    height: 65px;
    background: url(~@/assets/monitor/header.png) no-repeat center center;
    background-size: 50%;
    display: flex;
    justify-content: space-between;
    font-size: 16px;
    align-items: center;

    .back {
      cursor: pointer;
    }

    .back {
      display: flex;
      align-items: center;
    }
    .time {
      text-align: left;
      font-size: 14px;
    }
    img {
      height: 24px;
      width: 24px;
    }
  }

  .main {
    display: flex;
    margin: 20px 0;
    height: 614px;

    .monitorScreen:only-child {
      width: 100%;
      height: 100%;
    }

    .monitorScreen.length2 {
      height: 100%;
    }

    .mainLeft {
      position: relative;
      z-index: 1;
      width: calc(80% - 20px);
      display: flex;
      justify-content: space-between;
      flex-wrap: wrap;
      margin-right: 20px;
      align-content: space-between;
    }

    .mainRight {
      width: 20%;
      height: 100%;
      background: linear-gradient(360deg, rgba(0, 19, 45, 0.2) 0%, rgba(0, 28, 66, 0) 100%);
      box-shadow: 0px 0px 54px 0px rgba(0, 14, 40, 0.5);
      border: 1px solid;
      position: relative;
    }

    .mainRightHeader {
      line-height: 60px;
      background-image: linear-gradient(96deg, #06286b, #000b20);
      font-size: 24px;
      color: #75bcff;
      text-align: center;
      font-weight: bold;
    }

    .mainRightBody {
      height: calc(100% - 60px);
      padding: 1px 10% 0;
      margin: 0;

      li:first-child {
        border: 0;
      }

      li {
        height: 20%;
        border-top: 1px solid #0d396a;
        list-style: none;
        color: #83c3ff;

        .title {
          font-size: 18px;
          display: flex;
          align-items: center;
          padding: 20px 0 12px;
        }

        img {
          margin-right: 11px;
        }

        .number {
          font-size: 27px;
          font-weight: bold;
          color: #1990ff;
          margin-left: 32px;
        }
      }
    }
  }

  .footer {
    display: flex;
    height: 314px;
    padding: 14px;
    justify-content: space-between;
    background-color: #072d69;
    border: 1px solid #1c69d3;
    position: relative;

    .ant-tabs-extra-content {
      line-height: normal;

      .ant-btn ant-btn-link {
        height: auto;
      }
    }

    .footerLeft {
      width: 25%;
      display: flex;
      justify-content: center;
      align-items: center;

      img {
        width: 100%;
        max-height: 98%;
        border-radius: 2px;
      }
    }

    .footerRight {
      width: 75%;
      padding-left: 40px;

      .ant-table {
        color: #fff;
      }

      .ant-tabs-bar {
        border-color: #1b68d2;
      }

      .ant-tabs-tab {
        color: #6799c8;
      }

      .ant-tabs-tab-active {
        color: #fff;
      }

      .ant-tabs {
        color: #fff;

        .ant-tabs-nav .ant-tabs-tab {
          padding-top: 0;
        }

        .ant-tabs-nav-container {
          margin-top: 0;
        }
      }

      .ant-table-thead > tr > th {
        background: linear-gradient(96deg, #082867 0%, #06286a 100%);
        color: #1990ff;
        font-size: 16px;
      }

      .ant-table-thead > tr > th,
      .ant-table-tbody > tr > td {
        padding: 13px;
        border: 0;
      }

      .ant-table-thead > tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td,
      .ant-table-tbody > tr.ant-table-row-hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td,
      .ant-table-thead > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td,
      .ant-table-tbody > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td {
        background-color: #162d5a;
      }
    }
  }

  .quadrangle {
    position: relative;
  }

  .ant-table-fixed-header > .ant-table-content > .ant-table-scroll > .ant-table-body,
  .ant-table-header,
  .ant-table-fixed-header > .ant-table-content > .ant-table-scroll > .ant-table-body {
    background-color: #072d69;
  }
}

.monitorScreen {
  width: 49%;
  height: 297px;
  background-color: #00112c;
  position: relative;
  border: 1px solid transparent;
  z-index: 1001;

  .monitorScreenHeader {
    line-height: 40px;
    display: flex;
    justify-content: space-between;
    background-color: rgba(0, 0, 0, 0.4);
    font-size: 12px;
    position: absolute;
    top: 0;
    width: 100%;
    z-index: 200;
  }

  .monitorScreenHeaderLeft {
    color: #fff;
    font-size: 16px;
  }
  .ant-select-selection__rendered {
    margin-right: 32px;
  }
  .ant-select-selection {
    color: #fff !important;
    background: transparent !important;
    border: 1px solid #3572e2;
    margin-left: 10px;
    font-size: 14px;
    .ant-select-arrow {
      color: #1968ff;
    }
  }

  .monitorScreenHeaderRight {
    display: flex;
    align-items: center;
    color: #35b37e;
  }

  .circle {
    width: 5px;
    height: 5px;
    background-color: #35b37e;
    border-radius: 50%;
    margin-right: 5px;
  }

  .car {
    width: 20px;
    margin: 0 13px;
  }

  .fullscreen,
  .restore {
    margin: 0 23px;
  }

  .emergency {
    position: absolute;
    right: 0;
    bottom: 25px;
    width: 106px;
    line-height: 36px;
    background-color: #1990ff;
    border-radius: 100px 0 0 100px;
    text-align: center;
    color: #fff;
    font-weight: bold;
    border: 0;
    cursor: pointer;
    z-index: 10;
  }

  .emergency2 {
    position: absolute;
    right: 0;
    bottom: 70px;
    width: 106px;
    line-height: 36px;
    background-color: #f7b500;
    border-radius: 100px 0 0 100px;
    text-align: center;
    color: #fff;
    font-weight: bold;
    border: 0;
    cursor: pointer;
    z-index: 10;
  }

  .screenImg {
    width: 100%;
    height: 100%;
    vertical-align: top;
  }

  .offline {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }

  .corner {
    display: none;
  }
}

.error.monitorScreen {
  .monitorScreenHeaderRight {
    color: #fa6400;

    .circle {
      background-color: #fa6400;
    }
  }
}

.checked.monitorScreen {
  border-color: #0e5ac4;

  .corner {
    display: block;
  }
}

.monitorScreen:only-child {
  width: 100%;
}

.monitorScreen.dialog {
  height: 750px;

  .emergency {
    line-height: 76px;
    font-size: 30px;
    width: 200px;
  }
}

.monitorScreenDialog .ant-modal-body {
  padding: 0;
}

.monitorScreen.noVideo {
  display: flex;
  justify-content: center;
  align-items: center;
}

.carModalWrap {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(31, 31, 31, 0.7);
  align-items: center;
  z-index: 1009;
  display: flex;
  justify-content: center;
}

.carModal {
  color: #fff;
  width: 49%;
  width: 888px;
  margin: 0 0.5%;
  background-color: rgb(13, 24, 59);
  border-radius: 6px;

  .carModalMain {
    display: flex;
    height: 580px;
  }

  .carModelLeftHeader {
    position: relative;
    // display: flex;
    // justify-content: space-between;
    // margin: 10px 0;
    input {
      // margin-right: 10px;
    }
    .atable {
      position: absolute;
      top: 40px;
      width: 100%;
      z-index: 1;
      height: 380px;
      overflow-y: scroll;
    }
  }

  .ant-table-wrapper {
    background-color: #fff;
  }

  .carModalLeft {
    width: 54%;
    padding: 0 10px;

    img {
      max-width: 100%;
    }
  }

  .carModalRight {
    position: relative;
    width: 44%;
    padding: 0 2%;
  }

  .carModalRightHeader {
    background-color: #000c24;
    line-height: 88px;
    border-radius: 6px;
    font-size: 24px;
    display: flex;
    justify-content: center;
    width: 100%;
    flex-direction: row;
    justify-content: center;
    align-items: flex-end;
  }

  .carPlateNumber {
    color: #1990ff;
    font-weight: bold;
  }

  li {
    display: flex;
    align-items: center;
    font-size: 16px;
    line-height: 60px;
  }

  .label {
    font-size: 16px;
    color: #83c3ff;
    // margin-right: 10px;
  }

  .needPayMoney {
    color: #fa6400;
    font-size: 20px;
    font-weight: bold;
  }

  .btn {
    margin: 25px 10% 0;
    font-size: 22px;
    word-spacing: 0.5px;
    line-height: 60px;
    border-radius: 6px;
    font-weight: bold;
    justify-content: center;
    cursor: pointer;
  }

  .paidOpen {
    background-color: #39bb71;
  }

  .freeOpen {
    background-color: #1990ff;
  }

  .noEnterRecord {
    color: #f7b500;
    font-size: 24px;
    font-weight: bold;
    justify-content: center;
    margin: 36px 0;

    img {
      margin-right: 10px;
    }
  }

  .carModalRightContent {
    margin: 10px 0 0;
    padding: 0;
  }

  .carModalHeader {
    display: flex;
    justify-content: space-between;
    padding: 10px 20px;
    width: 100%;
    font-size: 16px;
  }
}

.corner {
  position: absolute;
  padding: 20px;
  border: 3px solid #1968ff;
  // z-index: 10;
}

.corner.topleft {
  border-width: 3px 0 0 3px;
  left: -3px;
  top: -3px;
}

.corner.topright {
  border-width: 3px 3px 0 0;
  right: -3px;
  top: -3px;
}

.corner.bottomleft {
  border-width: 0 0 3px 3px;
  bottom: -3px;
  left: -3px;
}

.corner.bottomright {
  border-width: 0 3px 3px 0;
  right: -3px;
  bottom: -3px;
}

@media screen and (max-device-width: 1440px) {
  .maintorPage {
    .main {
      .mainRightHeader,
      .carModalRightHeader,
      .noEnterRecord {
        font-size: 20px;
      }
    }
  }
}

@media screen and (max-device-width: 1080px) {
  .maintorPage {
    .main {
      .mainRightHeader,
      .carModalRightHeader,
      .noEnterRecord {
        font-size: 16px;
      }
    }
  }
}

.entryConfirm {
  position: absolute;
  width: 20em;
  line-height: 2em;
  border: 1px solid #ddd;
  border-radius: 4px;
  top: 45%;
  left: 50%;
  margin-left: -10em;
  background-color: #fff;
  color: #333;
  z-index: 1002;

  .content {
    font-weight: bold;
    padding: 10px 20px;
  }

  .plateNo {
    color: #1990ff;
    font-weight: bold;
  }

  .btns {
    text-align: center;
    border-top: 1px solid #ddd;
    display: flex;
    font-weight: bold;

    .accept {
      color: #1990ff;
      flex-grow: 1;
      border-left: 1px solid #ddd;
      padding: 5px 0;
      cursor: pointer;
    }

    .reject {
      color: #fa6400;
      flex-grow: 1;
      padding: 5px 0;
      cursor: pointer;
    }
  }
}
.flexCenter {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 10px;
  .ant-select-selection {
    border-color: #053b85;
    background: rgb(13, 24, 59);
    color: #fff;
  }
}
.iptStyle {
  border-color: #053b85;
  background: rgb(13, 24, 59);
  color: #fff;
}
.datapick .ant-calendar-picker-input {
  border-color: #053b85;
  background: rgb(13, 24, 59);
  color: #fff;
}
.datapick .ant-calendar-picker-input::-webkit-input-placeholder {
  /* WebKit browsers */
  color: #053b85;
  font-size: 16px;
}

.datapick .ant-calendar-picker-input::-moz-placeholder {
  /* Mozilla Firefox 19+ */
  color: #053b85;
  font-size: 16px;
}

.datapick .ant-calendar-picker-input:-ms-input-placeholder {
  /* Internet Explorer 10+ */
  color: #053b85;
  font-size: 16px;
}
.iptStyle::-webkit-input-placeholder {
  /* WebKit browsers */
  color: #053b85;
  font-size: 16px;
}

.iptStyle::-moz-placeholder {
  /* Mozilla Firefox 19+ */
  color: #053b85;
  font-size: 16px;
}

.iptStyle:-ms-input-placeholder {
  /* Internet Explorer 10+ */
  color: #053b85;
  font-size: 16px;
}
.ant-select-selection__placeholder {
  color: #053b85;
  font-size: 16px;
}
.rightBtn {
  background: #3673e1;
  border-color: #3673e1;
  color: #fff;
}
.footBtn {
  margin-top: 10px;
  width: 140px;
  height: 40px;
  font-size: 16px;
}
.payTips {
  border: 1px solid #1968ff;
  width: 220px;
  position: absolute;
  left: 0;
  top: 0px;
  background: #02102b;
  z-index: 1;
  font-size: 14px;
  .item {
    display: flex;
    align-items: center;
    justify-content: center;
    img {
      width: 20px;
      height: 14px;
      margin-right: 8px;
    }
    .op0 {
      opacity: 0;
    }
    .txt1 {
      width: 70px;
      color: #fff;
    }
    .txt2 {
      width: 70px;
      color: #fa6400;
      font-weight: bold;
    }
    .txt3 {
      width: 70px;
      color: #f1f1f1;
    }
  }
}
.topLeftSelect {
  margin-left: 13px;
}
.flexCenter .ant-radio-wrapper {
  color: #fff !important;
  font-size: 16px;
}
.ant-table-thead > tr > th,
.ant-table-tbody > tr > td {
  padding: 16px 0;
}
</style>
